import UIKit

var str = "Hello, playground"

print("Hello, playground")

var numVal = 15
numVal = 34
let myCons = 25

let cusNum:Double = 23.4

//字符串的拼接 使用 + String() 进行
let lable = "String is am"
let width = 94
let widthLable = lable + String(width)
print(widthLable)

//字符串的使用 \(apple) 参入变量
let apple = 3
let oranges = 5
let applesSummary = "I have \(apple) apples"
print(applesSummary)


//字典 使用方括号 [] 来创建数组和字典
var shoppingList = ["name","age","size"]
var  shopping:[String:String] =  ["name":"小号","age":"17","isBoy":"true"]
print(String("this is age") + shopping["age"]!)
//添加字段
shoppingList.append("")
shopping["title"] = "刘浩"
print(shopping)

//控制流 特点:括号可以省略，但是语句体的大括号是必须的
var individualScores = [75, 43, 103, 87, 12]

for item in individualScores{
    if item > 100{
        print("\(item) this is number max to 100")
    }
    
}

var optionalString:String? = nil
print(optionalString==nil)
var greeting = "Hello!"

if let name = optionalString {
    greeting = "Hello, \(name)"
}
print(greeting)

//元祖类型 由 N个 任意类型的数据组成
var position = (x:10.5,y:12) //position有2个元素，x、y是元素的名称
print(position.x)

var persions:(Int,Bool,String,Int) = (10,true,"xiaohao",12)
print("输出persion元祖类型变量 \(persions)")
print("输出persions 的 第三位\(persions.3)")

//可以使用下划线 _ 忽略某个元素的值
var perion = (25,"liuhao")
var (age,_) = perion
print(age)

//元祖类型小练习
var yzData = (1 ,"小号",true);
func handle(param:(Int,String,Bool))->(Int,String,Bool){
    var data_temp = param;
    data_temp.0 = param.0+10;
    data_temp.1 = param.1+String("哈哈")
    data_temp.2 = !param.2
    return data_temp;
}

print(yzData)
print("-------------")
print(handle(param: yzData))
//输出
//(1, "小号", true)
//-------------
//(11, "小号哈哈", false)



//区间运算符
 //1> 闭区间运算符 a...b  包含从 a 到 b（包括 a 和 b）的所有值的区间
 //2> 半开区间运算符 a..<b 定义一个从 a 到 b 但不包括 b 的区间
 //3> 单侧区间 表达往一侧无限延伸的区间 如 2...

var a = 1...4
print("a 的范围是\(a)")

var b = 1..<4
print("b 的范围是\(b)")

var c = 1...
print("c 的范围是 \(c)")


//for in 循环
for item in 1...10 {
    print(item)
}

//stride 相当于步长的概念 to 不包含末尾 through包含末尾
//reversed() 反向 倒叙

// for in 步长
for item in stride(from: 1, to: 11, by: 2) {
    print(item)
}

// for in 步长
for item in stride(from: 1, through: 11, by: 2).reversed() {
    print(item)
}


//continue 和 break 与java的使用方法一样


//隐式展开
var aValue:Int! = 100;
var bValue:Int = aValue;
//会打印出100的值
print(bValue)


//if+可绑定选项
var ifValue:Int! = 100
if let value = ifValue {
    print("ifValue 有值是：\(value)")
}else{
    print("ifValue 没有值")
}


//字符串的操作
var strValue = "小浩ABCDEddd"

//获取某一个角标的值 []里面放 String.Index 的对象
print(strValue[strValue.startIndex]);

//获取某一个角标的值 [] index(before: 前一个
//print(strValue[strValue.index(before: strValue.startIndex)])

//offsetBy 偏移位置
print(strValue[strValue.index(strValue.startIndex, offsetBy: 2)])

//区间 String.Index
var strat = strValue.startIndex;
var end = strValue.index(strValue.startIndex, offsetBy: 4)
print(strValue[strat...end])

//firstIndex 获取第一次出现的位置
var st = strValue.firstIndex(of: "A") ?? strValue.endIndex
print(strValue[strValue.startIndex...st])

//获取前五位 prefix（）
print(strValue.prefix(5))

//判断字符串是否包含
strValue.contains("AB")
//判断字符串是否包含--只要一个字符在字符串中就返回true
strValue.contains(where: String.contains("Ac"))
//判断字符串是否包含前缀 hasPrefix
strValue.hasPrefix("小浩")
//判断字符串是否包含后缀 hasSuffix
strValue.hasSuffix("ddd")
//追加字符串 append
strValue.append("我是最牛逼的")
//字符串插入 在第二个位置插入 fff  at：String.Index
strValue.insert(contentsOf: "ffff", at: strValue.index(strValue.startIndex, offsetBy: 2))
//替换 区间+目标字符串
strValue.replaceSubrange(strat...end, with: "ssss")
//替换目标字符串并返回一个新的字符串 AB 替换成 ab
strValue.replacingOccurrences(of: "AB", with: "ab")
//删除区间
strValue.removeSubrange(strat...end)



//遍历字符串
for item in strValue {
    print(item)
}
for index in 0..<strValue.count {
    print(strValue[strValue.index(strValue.startIndex, offsetBy: index)])
}


//多行字符串 使用“”“包起来
var moreStr =
"""
dwadawawd
dawda
awdawdawd
"""
print(moreStr)

//打印 “abc” 使用#包起来
var moreStrs = #"“大王打底袜”"#
print(moreStrs)



//------集合使用--------
//集合的排序
var array = ["A","B","C","D","E"]
array.sort(by: {(s1,s2)->Bool in
    if(s1>s2){
        return true
    }
    return false
})

print(array)

//赛选 会返回一个新的集合
var newArray = array.filter { (str) -> Bool in
    if(str=="B"){
        return false
    }
    return true
}

print(newArray)

//遍历 array[0...] 表示从0-结尾
for item in array[0...] {
    print(item)
}


//Set集合的使用
var set_list:Set<String> = ["android","ios","win","Linux","winPhone","鸿蒙"]
//遍历
for item in set_list {
    print(item)
}
//合并两个Set返回新的Set（会去处重复的）
var data_set:Set<String>  = ["android","小浩","晓麒","小贾"]
var new_data_set = set_list.union(data_set)
//输出：["ios", "Linux", "鸿蒙", "晓麒", "小浩", "winPhone", "小贾", "android", "win"]
print(new_data_set)
//返回两个set中不相同的部分
var new_data_dif = set_list.symmetricDifference(data_set)
//输出["winPhone", "小浩", "Linux", "win", "鸿蒙", "ios", "晓麒", "小贾"]
print("两个set中不相同的部分 \(new_data_dif)")
//两个集合比较，返回前面set中与后面set不同的数据
var new_data_befor = set_list.subtracting(data_set)
//输出 ["Linux", "鸿蒙", "winPhone", "ios", "win"]
print(new_data_befor)



//-------字典的使用--------
//1>申明的方式
var ad:Dictionary<String,String> = ["a":"小浩","b":"小琪"]
print(ad)
var adc:[String:Int] = ["小":10,"琪":20]
print(adc)
var ads = ["小":10,"琪":20]
print(ads)
//2>取值 使用键取
print(ad["a"] ?? "没有值")
//3>修改值
ad["a"] = "小刘"
//有就去更新，没有就添加
ad.updateValue("校长", forKey: "a")
print(ad)
//可选项绑定 如果有指定的key 就附值给item 执行if语句 如果为nil就不执行
if let item = ad["a"] {
    print(item)
}
//删除key
ad.removeValue(forKey: "a")
//排序操作
var filterAd =  ad.filter({(key,value) -> Bool in
    if(key=="b"){
        return true
    }
    return false
});
print(filterAd)

//循环打印
for (key,value) in ad {
    print("key---\(key)---|---value---\(value)")
}



//---------方法的使用和申明----------
func test()->Int{
    return 100
}
print(test())

//可变参数方法
func chageMethod(name:String...){
    for str in name {
        print(str)
    }
}
chageMethod(name: "小浩","晓琪")

func chageMethod2(persion:(n1:String,n2:Int))->(String,Int){
    var value:(name:String,age:Int)
    value.name = persion.n1+"刘"
    value.age = persion.n2+5
    return value
}

print(chageMethod2(persion:(n1:"小浩",n2:5)))

//outname inname   outname可以使用_忽略 (_ inname:String)
func nameTest(outname inname:String){
    print(inname)
}
nameTest(outname: "小浩")

//assert使用
func testAssert(param:Int){
    if(param>4){
        assert(false,"停止运行了")
    }
    print("值为---\(param)")
}
testAssert(param: 3)

//guard语句 相当于if语句 与判断相反
func testGuard(param:Int){
    guard param>10 else {
        print("命中guard里面的代码 \(param)")
        return
    }
    print("小浩是GG")
}
testGuard(param: 15)

//guard语句的可选项绑定
var guardA:String? = nil
func testGuardLet(param:String?){
    guard let value = param else {
        print("命中Guard语句中的代码")
        return
    }
    print(value)
}
testGuardLet(param: guardA)

//inout 关键字的使用 需要通过一个函数改变函数外面变量的值(将一个值类型参数以引用方式传递)
var inA = 10;
func inoutMethod(param:inout Int){
    param = param*2
}
print("inA 以前的值是 \(inA)")
inoutMethod(param: &inA)
print("inA 调用后的值是 \(inA)")

//函数类型的申明和使用
func funTest()->Void{
    print("wo shi xiao hao")
}
var funTestA:()->Void
var funTestB:(Int,String)->Bool
//附值
funTestA = funTest
funTestA()

//匿名函数
var funTestC:()->Void = {()->Void in
    print("匿名函数")
}
funTestC()

//函数作为函数参数传入
func funTestD(param:()->Void){
    param()
}

funTestD(param: funTest)

funTestD(param: {()->Void in
    print("匿名参数调用")
})

//函数作为返回值使用
func funTestE(param:Bool)->(Int)->Int{
    func fune(a:Int)->Int{
        return a+a
    }
    
    func funf(b:Int)->Int{
        return b*b
    }
    return param ? fune : funf
}

var funs = funTestE(param: false)
funs(10)







































